package com.xiaoshuidi.cloud.module.member.service.securitycheckprogram;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.module.member.mapper.securitycheckprogram.SecurityCheckProgramMapper;
import com.xiaoshuidi.cloud.module.member.pojo.securitycheckprogram.SecurityCheckProgram;
import com.xiaoshuidi.cloud.module.member.pojo.securitycheckprogram.SecurityCheckProgramGridders;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import com.xiaoshuidi.cloud.module.member.controller.admin.securitycheckprogram.vo.*;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.module.member.convert.securitycheckprogram.SecurityCheckProgramConvert;
import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.member.enums.ErrorCodeConstants.SECURITY_CHECK_PROGRAM_NOT_EXISTS;

/**
 * 安全检查项目 Service 实现类
 *
 * @author hans.zhang
 */
@Slf4j
@Service
@Validated
public class SecurityCheckProgramServiceImpl extends ServiceImpl<SecurityCheckProgramMapper, SecurityCheckProgram> implements SecurityCheckProgramService {

    @Resource
    private SecurityCheckProgramMapper securityCheckProgramMapper;
    @Resource
    private SecurityCheckProgramGriddersService securityCheckProgramGriddersService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createSecurityCheckProgram(SecurityCheckProgramCreateReqVO createReqVO) {
        log.info("创建安全检查项目,参数:{}", JsonUtils.toJsonString(createReqVO));
        // 插入
        SecurityCheckProgram securityCheckProgram = SecurityCheckProgramConvert.INSTANCE.convert(createReqVO);
        securityCheckProgramMapper.insert(securityCheckProgram);
        // 记录网格员
        SecurityCheckProgramGriddersCreateReqVO reqVO = new SecurityCheckProgramGriddersCreateReqVO();
        reqVO.setSecurityCheckProgramId(securityCheckProgram.getId());
        reqVO.setGridders(createReqVO.getGridders());
        securityCheckProgramGriddersService.createSecurityCheckProgramGridders(reqVO);
        // 返回
        return securityCheckProgram.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateSecurityCheckProgram(SecurityCheckProgramUpdateReqVO updateReqVO) {
        // 校验存在
        validateSecurityCheckProgramExists(updateReqVO.getId());
        // 更新
        SecurityCheckProgram updateObj = SecurityCheckProgramConvert.INSTANCE.convert(updateReqVO);

        // 记录网格员
        SecurityCheckProgramGriddersCreateReqVO reqVO = new SecurityCheckProgramGriddersCreateReqVO();
        reqVO.setSecurityCheckProgramId(updateReqVO.getId());
        reqVO.setGridders(updateReqVO.getGridders());
        securityCheckProgramGriddersService.upodateSecurityCheckProgramGridders(reqVO);

        securityCheckProgramMapper.updateById(updateObj);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteSecurityCheckProgram(Long id) {
        // 校验存在
        validateSecurityCheckProgramExists(id);
        // 删除
        securityCheckProgramMapper.deleteById(id);
        // 删除网格员
        securityCheckProgramGriddersService.deleteByCheckProgramId(id);
    }

    private void validateSecurityCheckProgramExists(Long id) {
        if (securityCheckProgramMapper.selectById(id) == null) {
            throw exception(SECURITY_CHECK_PROGRAM_NOT_EXISTS);
        }
    }

    @Override
    public SecurityCheckProgramRespVO getSecurityCheckProgram(Long id) {
        SecurityCheckProgram securityCheckProgram = securityCheckProgramMapper.selectById(id);
        SecurityCheckProgramRespVO securityCheckProgramRespVO = SecurityCheckProgramConvert.INSTANCE.convert(securityCheckProgram);
        // 查询网格员
        List<Gridders> griddersList = new ArrayList<>();
        List<SecurityCheckProgramGridders> securityCheckProgramGriddersList = securityCheckProgramGriddersService.getSecurityCheckProgramGriddersList(securityCheckProgram.getId());
        securityCheckProgramGriddersList.forEach(securityCheckProgramGridders -> {
            Gridders gridders = new Gridders();
            gridders.setId(securityCheckProgramGridders.getGriddersId());
            gridders.setName(securityCheckProgramGridders.getGriddersName());
            griddersList.add(gridders);
        });
        securityCheckProgramRespVO.setGridders(griddersList);
        return securityCheckProgramRespVO;
    }

    @Override
    public List<SecurityCheckProgram> getSecurityCheckProgramList(Boolean status) {
        LambdaQueryWrapper<SecurityCheckProgram> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ObjectUtil.isNotEmpty(status), SecurityCheckProgram::getStatus, status);
        wrapper.orderByDesc(SecurityCheckProgram::getCreateTime);
        return securityCheckProgramMapper.selectList(wrapper);
    }

    @Override
    public PageResult<SecurityCheckProgramRespVO> getSecurityCheckProgramPage(SecurityCheckProgramPageReqVO pageReqVO) {
        QueryWrapper<SecurityCheckProgram> wrapper = Wrappers.query();
        wrapper.eq("mscp.deleted", false);
        wrapper.between(ObjectUtil.isAllNotEmpty(pageReqVO.getCreateTimeStart(), pageReqVO.getCreateTimeEnd()), "mscp.create_time", pageReqVO.getCreateTimeStart(), pageReqVO.getCreateTimeEnd());
        wrapper.and(ObjectUtil.isNotEmpty(pageReqVO.getSearchBox()), wrap -> {
            wrap.like("mscp.name", pageReqVO.getSearchBox())
                    .or()
                    .like("mscpg.gridders_name", pageReqVO.getSearchBox());
        });
        wrapper.orderByDesc("mscp.create_time");
        Page<SecurityCheckProgramRespVO> page = securityCheckProgramMapper.page(new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize()), wrapper);
        page.getRecords().forEach(securityCheckProgramRespVO -> {
            List<SecurityCheckProgramGridders> securityCheckProgramGriddersList = securityCheckProgramGriddersService.getSecurityCheckProgramGriddersList(securityCheckProgramRespVO.getId());
            List<Gridders> griddersList = new ArrayList<>();
            securityCheckProgramGriddersList.forEach(securityCheckProgramGridders -> {
                Gridders gridders = new Gridders();
                gridders.setId(securityCheckProgramGridders.getGriddersId());
                gridders.setName(securityCheckProgramGridders.getGriddersName());
                griddersList.add(gridders);
            });
            securityCheckProgramRespVO.setGridders(griddersList);
        });
        return new PageResult<>(page.getRecords(), page.getTotal());
    }

    @Override
    public List<SecurityCheckProgramRespVO> getSecurityCheckProgramList(SecurityCheckProgramExportReqVO exportReqVO) {
        QueryWrapper<SecurityCheckProgram> wrapper = Wrappers.query();
        wrapper.eq("mscp.deleted", false);
        wrapper.between(ObjectUtil.isAllNotEmpty(exportReqVO.getCreateTimeStart(), exportReqVO.getCreateTimeEnd()), "mscp.create_time", exportReqVO.getCreateTimeStart(), exportReqVO.getCreateTimeEnd());
        wrapper.and(ObjectUtil.isNotEmpty(exportReqVO.getSearchBox()), wrap -> {
            wrap.like("mscp.name", exportReqVO.getSearchBox())
                    .or()
                    .like("mscpg.gridders_name", exportReqVO.getSearchBox());
        });
        wrapper.orderByDesc("mscp.create_time");
        List<SecurityCheckProgramRespVO> securityCheckProgramRespVOS = securityCheckProgramMapper.list(wrapper);
        securityCheckProgramRespVOS.forEach(securityCheckProgramRespVO -> {
            List<SecurityCheckProgramGridders> securityCheckProgramGriddersList = securityCheckProgramGriddersService.getSecurityCheckProgramGriddersList(securityCheckProgramRespVO.getId());
            List<Gridders> griddersList = new ArrayList<>();
            securityCheckProgramGriddersList.forEach(securityCheckProgramGridders -> {
                Gridders gridders = new Gridders();
                gridders.setId(securityCheckProgramGridders.getGriddersId());
                gridders.setName(securityCheckProgramGridders.getGriddersName());
                griddersList.add(gridders);
            });
            securityCheckProgramRespVO.setGridders(griddersList);
        });
        return securityCheckProgramRespVOS;
    }

    /**
     * 获取我的项目列表
     *
     * @param loginUserId 当前登录用户
     * @return
     */
    @Override
    public List<GetMyProgramRespVO> getMyProgram(Long loginUserId) {
        List<SecurityCheckProgram> securityCheckPrograms = securityCheckProgramMapper.getMyProgram(loginUserId);
        return SecurityCheckProgramConvert.INSTANCE.convert(securityCheckPrograms);
    }

}
